home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 March / macformat-022.iso / Shareware City / Info / csmp / csmp-v3-064.txt < prev    next >
Encoding:
Internet Message Format  |  1994-11-22  |  51.8 KB  |  [TEXT/unix]

  1. From: pottier@clipper.ens.fr (Francois Pottier)
  2. Subject: csmp-digest-v3-064
  3. Date: Sat, 8 Oct 1994 14:49:41 +0100 (MET)
  4.  
  5. C.S.M.P. Digest             Sat, 08 Oct 94       Volume 3 : Issue 64
  6.  
  7. Today's Topics:
  8.  
  9.         Help!! argc, argv on Macintosh
  10.         How to Check if drivers are open
  11.         Is it possible to notify another mac?
  12.         Memory moving and Inits
  13.         Self-disposing notification crashes
  14.         [CWWWW] PowerPlant Tour document available
  15.  
  16.  
  17.  
  18. The Comp.Sys.Mac.Programmer Digest is moderated by Francois Pottier
  19. (pottier@clipper.ens.fr).
  20.  
  21. The digest is a collection of article threads from the internet newsgroup
  22. comp.sys.mac.programmer.  It is designed for people who read c.s.m.p. semi-
  23. regularly and want an archive of the discussions.  If you don't know what a
  24. newsgroup is, you probably don't have access to it.  Ask your systems
  25. administrator(s) for details.  If you don't have access to news, you may
  26. still be able to post messages to the group by using a mail server like
  27. anon.penet.fi (mail help@anon.penet.fi for more information).
  28.  
  29. Each issue of the digest contains one or more sets of articles (called
  30. threads), with each set corresponding to a 'discussion' of a particular
  31. subject.  The articles are not edited; all articles included in this digest
  32. are in their original posted form (as received by our news server at
  33. nef.ens.fr).  Article threads are not added to the digest until the last
  34. article added to the thread is at least two weeks old (this is to ensure that
  35. the thread is dead before adding it to the digest).  Article threads that
  36. consist of only one message are generally not included in the digest.
  37.  
  38. The digest is officially distributed by two means, by email and ftp.
  39.  
  40. If you want to receive the digest by mail, send email to listserv@ens.fr
  41. with no subject and one of the following commands as body:
  42.     help                        Sends you a summary of commands
  43.     subscribe csmp-digest Your Name    Adds you to the mailing list
  44.     signoff csmp-digest            Removes you from the list
  45. Once you have subscribed, you will automatically receive each new
  46. issue as it is created.
  47.  
  48. The official ftp info is //ftp.dartmouth.edu/pub/csmp-digest.
  49. Questions related to the ftp site should be directed to
  50. scott.silver@dartmouth.edu. Currently no previous volumes of the CSMP
  51. digest are available there.
  52.  
  53. Also, the digests are available to WAIS users.  To search back issues
  54. with WAIS, use comp.sys.mac.programmer.src. With Mosaic, use
  55. http://www.wais.com/wais-dbs/comp.sys.mac.programmer.html.
  56.  
  57.  
  58. -------------------------------------------------------
  59.  
  60. >From victor chong <victorc@sleepy.cc.utexas.edu>
  61. Subject: Help!! argc, argv on Macintosh
  62. Date: 22 Sep 1994 21:19:15 GMT
  63. Organization: UT Austin
  64.  
  65. Hi,
  66.     I was wondering if someone could enlighten me concerning
  67. the usage of argv and argc when programming on the Macintosh.
  68. I'm using Symantec C++.
  69.     Does the Mac allows this kind of communication with the
  70. OS or is there another method.
  71.     Any kind of help will be much welcome.
  72.     Thank you very much.
  73.     
  74.     
  75.     
  76.     
  77. victor
  78.  
  79. victorc@sleepy.cc.utexas.edu
  80.  
  81. +++++++++++++++++++++++++++
  82.  
  83. >From Eric.M.Kidd@dartmouth.edu (Eric M. Kidd)
  84. Date: 23 Sep 1994 00:11:36 GMT
  85. Organization: Dartmouth College, Hanover, NH
  86.  
  87. argc and argv do not work at all on any normal mac setup. Sorry.
  88.  
  89. The following program fragment gives an idea of how to get the
  90. old-fashioned app params (files to open or print). If you want to do
  91. anything more complicated, you'll need to use Apple Events.
  92.  
  93. /* openingFiles( )
  94. **
  95. ** Determine if we have parameters. The old-style app parameters are
  96. used for
  97. ** the sake of SPEED. Apple Events are too slow, and I only have
  98. partial docs.
  99. ** Help in acquiring copies of Inside Macintosh always welcome...
  100. */
  101.  
  102. Boolean openingFiles( )
  103. {
  104.     short message;
  105.     short count;
  106.     
  107.     CountAppFiles( &message, &count );
  108.     
  109.     return ( message == 0 && count > 0 );
  110. }
  111.  
  112. /* openFiles( )
  113. **
  114. ** Go through files one by one, processing them along the way.
  115. */
  116.  
  117. void openFiles( )
  118. {
  119.     FSSpec cur;
  120.     AppFile aFile;
  121.     short count;
  122.     short i;
  123.     short mess;
  124.     
  125.     /* I'm not bothering to check for print messages--my app shouldn't get
  126. any */
  127.     CountAppFiles( &mess, &count );
  128.     
  129.     for ( i = 1; i <= count; i++ )
  130.     {
  131.         /* get file and convert from working dir to FSSpec */
  132.         GetAppFiles( i, &aFile );
  133.         FSMakeFSSpec( aFile.vRefNum, 0, aFile.fName, &cur );
  134.         
  135.         processFile( &cur );
  136.     }
  137. }
  138.  
  139. main( )
  140. {
  141.     initMacintosh( );
  142.     initApplication( );
  143.     
  144.     if ( openingFiles( ) )
  145.         openFiles( );
  146.     else
  147.         runApplication( );
  148. }
  149.  
  150. +++++++++++++++++++++++++++
  151.  
  152. >From ruhl@du.edu (ROBERT A. UHL )
  153. Date: Fri, 23 Sep 1994 15:34:11 GMT
  154. Organization: University of Denver
  155.  
  156.   Does anybody have the format of the Handle returned by
  157. GetAppParms()? I don't have IM and have to figure out what the
  158. functions do from the headers. Any help would be appreciated.
  159. -- 
  160. - ------------------------------------
  161. | Bob Uhl | Spectre                  |
  162. | U of D  | Baron Robert von Raetzin |
  163.  
  164. +++++++++++++++++++++++++++
  165.  
  166. >From Carl R. Osterwald <carl_osterwald@nrel.gov>
  167. Date: Fri, 23 Sep 1994 20:48:32 GMT
  168. Organization: National Renewable Energy Laboratory
  169.  
  170. In article <35ssck$m3a@geraldo.cc.utexas.edu> victor chong,
  171. victorc@sleepy.cc.utexas.edu writes:
  172. >    I was wondering if someone could enlighten me concerning
  173. >the usage of argv and argc when programming on the Macintosh.
  174. >I'm using Symantec C++.
  175. >    Does the Mac allows this kind of communication with the
  176. >OS or is there another method.
  177.  
  178. Just use the Symantec console package.  You will need to add one key
  179. element, a ccommand() call, before you access argv/argc.  This puts up a
  180. dialog box that allows you to type in the command line parameters. 
  181. ccommand() was documented in the Think C 5 manuals, in 6 and 7 it is
  182. online inside the free version of Think Reference (I have not verified
  183. this personally).
  184.  
  185. For disk I/O be sure to check the c.s.m.p PD programming FAQ compiled by
  186. Jon Watte.
  187.  
  188. +++++++++++++++++++++++++++
  189.  
  190. >From rrk@rahul.net (Bob R. Kenyon)
  191. Date: Sat, 24 Sep 1994 05:54:04 GMT
  192. Organization: La Casita de Las Pulgas, San Jose, CA
  193.  
  194. In article <35ssck$m3a@geraldo.cc.utexas.edu>, victor chong
  195. <victorc@sleepy.cc.utexas.edu> wrote:
  196.  
  197. > Hi,
  198. >         I was wondering if someone could enlighten me concerning
  199. > the usage of argv and argc when programming on the Macintosh.
  200. > I'm using Symantec C++.
  201. >         Does the Mac allows this kind of communication with the
  202. > OS or is there another method.
  203. >         Any kind of help will be much welcome.
  204. >         Thank you very much.
  205.  
  206. Yeah, if you look in Think Reference, they talk about a function called
  207. ccommand. When your program starts, it throws up a window that allows you
  208. to redirect input and output, and enter command line arguments. It's
  209. pretty funny actually, but not really "Mac" in behavior.
  210.  
  211. Their code example looks like this:
  212.  
  213.  
  214. /* CODE EXAMPLE #1 */
  215. #include <stdio.h>
  216. #include <console.h>
  217.  
  218. main(int argc, char **argv)
  219. {
  220.    int i;
  221.  
  222.    argc = ccommand(&argv);  // this is the command that throws up the window
  223.  
  224.    for (i=0; i<argc; i++)
  225.       printf ("%s ", argv[i]);
  226.  
  227.    printf ("\n");
  228. }
  229.  
  230. I use this technique all the time for my programming classes, because they
  231. haven't covered any kind of windowing stuff. 
  232.  
  233. Hope this helps,
  234. Bob
  235.  
  236. -- 
  237. Bob Kenyon                           | "Pilots take no special joy
  238. Beautiful Downtown San Jose, CA      |  in walking. Pilots like
  239. rrk@rahul.net                        |  flying." -- Neil Armstrong
  240.  
  241. ---------------------------
  242.  
  243. >From ferrari@netaxs.com (Darrell Turner)
  244. Subject: How to Check if drivers are open
  245. Date: Thu, 22 Sep 1994 13:26:38 -0500
  246. Organization: Haha, None here
  247.  
  248. I'm trying to figure out how to check if a driver is open by only
  249. specifying the driver name.  I want it to work for .IPP .AOut, and others
  250. such as ram serail drivers for Hurdlers, etc.
  251.  
  252. My problem is that I can't figure out if it's open without first knowing
  253. the driver unit number.  I was going to walk the UnitTable checking for the
  254. Driver Name  in the DCtlEntry, but I soon discovered that the name is in
  255. there.  This is my current code, and it doesn't work, how can I get this
  256. working?  (The GetNamedResource returns nil, even on stuff I know is in the
  257. System file like .AOut.
  258.  
  259.     function GetNamedDCtlEntry (driverName: str255): DCtlHandle;
  260.         type
  261.             Ptr2Word = ^integer;
  262.             Ptr2Byte = ^byte;
  263.         const
  264.             UnitNtryCnt = $1D2; {[GLOBAL VAR]  count of entries in unit table
  265. [word]}
  266.             RomMapInsert = $B9E;{[GLOBAL VAR] (byte) determines if we should link in
  267. map}
  268.  
  269.         var
  270.             rID: integer;
  271.             rType: ResType;
  272.             hand: handle;
  273.     begin
  274.         SetResLoad(false);
  275.         Ptr2Byte(RomMapInsert)^ := 1;
  276.         hand := GetNamedResource('DRVR', driverName);
  277.         SetResLoad(true);
  278.         GetResInfo(hand, rID, rType, driverName);
  279.         if (rID >= 0) and (rID <= Ptr2Word(UnitNtryCnt)^) then
  280.             GetNamedDCtlEntry := GetDCtlEntry(rID)
  281.         else
  282.             GetNamedDCtlEntry := nil;
  283.     end;
  284.  
  285. begin
  286.     dctl := GetNamedDCtlEntry('.IPP');
  287.     if dCtl = nil then
  288.         Quit(noErr);
  289.     Init;
  290.     repeat
  291.         HandleEvents;
  292.     until (BitTst(@dctl^^.dCtlFlags, 5) or done);
  293.  {...}
  294. end.
  295.  
  296. +++++++++++++++++++++++++++
  297.  
  298. >From resnick@uiuc.edu (Pete Resnick)
  299. Date: Fri, 23 Sep 1994 12:36:16 -0500
  300. Organization: University of Illinois at Urbana-Champaign
  301.  
  302. In article <ferrari-220994132639@slip-55.netaxs.com>, ferrari@netaxs.com (Darrell Turner) wrote:
  303.  
  304. > I'm trying to figure out how to check if a driver is open by only
  305. > specifying the driver name.  I want it to work for .IPP .AOut, and others
  306. > such as ram serail drivers for Hurdlers, etc.
  307. > My problem is that I can't figure out if it's open without first knowing
  308. > the driver unit number.  I was going to walk the UnitTable checking for the
  309. > Driver Name  in the DCtlEntry, but I soon discovered that the name is in
  310. > there.
  311.  
  312. Yes it is. It's in the driver itself, which is pointed to by the DCtl
  313. entry. Here's some code (in C; the conversion to Pascal is pretty easy):
  314.  
  315. /* Structure of the driver resource */
  316. typedef struct {
  317.     short drvrFlags;
  318.     short drvrDelay;
  319.     short drvrEMask;
  320.     short drvrMenu;
  321.     short drvrOpen;
  322.     short drvrPrime;
  323.     short drvrCtl;
  324.     short drvrStatus;
  325.     short drvrClose;
  326.     unsigned char drvrName[];
  327.     unsigned char drvrRoutines[];
  328. } DriverStruct, *DriverPtr, **DriverHandle;
  329.  
  330. #if define(__SYSEQU__)
  331. #define UTABLEBASE  (* (DCtlHandle **)UTableBase)
  332. #define UNITNTRYCNT (* (short *)UnitNtryCnt)
  333. #elif defined(__LOWMEM__)
  334. #define UTABLEBASE  (DCtlHandle *)LMGetUTableBase()
  335. #define UNITNTRYCNT LMGetUnitNtryCnt()
  336. #else
  337. #define UTABLEBASE  UTableBase
  338. #define UNITNTRYCNT UnitNtryCnt
  339. #endif
  340.  
  341. #ifndef dOpened
  342. #   define dOpened      0x0020
  343. #endif /* dOpened */
  344. #ifndef dRAMBased
  345. #   define dRAMBased    0x0040
  346. #endif /* dRAMBased */
  347.  
  348. short GetDrvrRefNum(StringPtr drvrName)
  349. {
  350.   short unitNum;
  351.   DCtlPtr curDCtlPtr, *curDCtlHndl, **UTableEntry;
  352.   DriverPtr curDrvrPtr;
  353.     
  354.   /* Walk through the Unit Table */
  355.   UTableEntry = UTABLEBASE;
  356.   for(unitNum = 0; unitNum < UNITNTRYCNT; ++unitNum) {
  357.     if((curDCtlHndl = *UTableEntry++) != nil) {
  358.             
  359.       curDCtlPtr = *curDCtlHndl;
  360.             
  361.       /* Get the pointer to the driver */
  362.       curDrvrPtr = (DriverPtr)curDCtlPtr->dCtlDriver;
  363.  
  364.       /* If this is a RAM driver, it's a handle. ROM is a pointer */
  365.       if((curDCtlPtr->dCtlFlags & dRAMBased) && (curDrvrPtr != nil))
  366.         curDrvrPtr = *(DriverPtr *)curDrvrPtr;
  367.             
  368.       /* Does the driver name match? */
  369.       if(curDrvrPtr != nil)
  370.         if(EqualString(drvrName, curDrvrPtr->drvrName, false, true))
  371.           return(~unitNum);
  372.     }
  373.   }
  374.   return(0);
  375. }
  376.  
  377. Boolean IsDriverOpen(StringPtr drvrName)
  378. {
  379.   short unitNum;
  380.   DCtlPtr curDCtlPtr, *curDCtlHndl, **UTableEntry;
  381.   DriverPtr curDrvrPtr;
  382.     
  383.   /* Walk through the Unit Table */
  384.   UTableEntry = UTABLEBASE;
  385.   for(unitNum = 0; unitNum < UNITNTRYCNT; ++unitNum) {
  386.     if((curDCtlHndl = *UTableEntry++) != nil) {
  387.             
  388.       curDCtlPtr = *curDCtlHndl;
  389.             
  390.       /* Get the pointer to the driver */
  391.       curDrvrPtr = (DriverPtr)curDCtlPtr->dCtlDriver;
  392.  
  393.       /* If this is a RAM driver, it's a handle. ROM is a pointer */
  394.       if((curDCtlPtr->dCtlFlags & dRAMBased) && (curDrvrPtr != nil))
  395.         curDrvrPtr = *(DriverPtr *)curDrvrPtr;
  396.             
  397.       /* Does the driver name match? */
  398.       if(curDrvrPtr != nil)
  399.         if(EqualString(drvrName, curDrvrPtr->drvrName, false, true))
  400.           return((curDCtlPtr->dCtlFlags & dOpened) != 0);
  401.     }
  402.   }
  403.   return(false);
  404. }
  405.  
  406. Note: There is an omission in the Universal headers LowMem.h because it
  407. does not define LMGetUnitNtryCnt or LMSetUnitNtryCnt. For the 68000
  408. versions, add:
  409.  
  410. #define LMGetUnitNtryCnt() (* (short *) 0x01D2)
  411.  
  412. #define LMSetUnitNtryCnt(UnitNtryCntValue) ((* (short *) 0x01D2) = (UnitNtryCntValue))
  413.  
  414. I don't know what to do about the PowerPC versions.
  415.  
  416. pr
  417. -- 
  418. Pete Resnick    (...so what is a mojo, and why would one be rising?)
  419. Doctoral Student - Philosophy Department, Gregory Hall, UIUC
  420. System manager - Cognitive Science Group, Beckman Institute, UIUC
  421. Internet: resnick@uiuc.edu
  422.  
  423. +++++++++++++++++++++++++++
  424.  
  425. >From csuley@netcom.com (Christopher S. Suley)
  426. Date: Sat, 24 Sep 1994 05:58:12 GMT
  427. Organization: NETCOM On-line Communication Services (408 261-4700 guest)
  428.  
  429.  
  430. Here's some code I use to find a driver in the unit table.
  431. It's lightly adapted from Pete Resnick's excellent Driver 2.2,
  432. available at sumex and umich and mirrors thereof.
  433. It's in C, but the translation to Pascal should be pretty easy.
  434.  
  435.  
  436. typedef struct
  437. {
  438.   short drvrFlags;
  439.   short drvrDelay;
  440.   short drvrEMask;
  441.   short drvrMenu;
  442.   short drvrOpen;
  443.   short drvrPrime;
  444.   short drvrCtl;
  445.   short drvrStatus;
  446.   short drvrClose;
  447.   unsigned char drvrName[1]; /* actually variable length p-string */
  448. }
  449. DriverStruct, *DriverPtr;
  450.  
  451. short
  452. FindDriver( void )
  453. {
  454.   Str255      drvrName;
  455.   DCtlHandle  hCurDCE;
  456.   DriverPtr   pCurDrvr;
  457.   short       sDrvrNum;
  458.  
  459.   GetIndString( drvrName, krMiscStrings, ksiDriverNameIndex );
  460.  
  461.   for ( sDrvrNum = LMGetUnitNtryCnt() ; sDrvrNum >= 0 ; --sDrvrNum )
  462.   {
  463.     hCurDCE = GetDCtlEntry( ~sDrvrNum );
  464.     if ( hCurDCE )
  465.     {
  466.       pCurDrvr = ( DriverPtr ) (**hCurDCE).dCtlDriver;
  467.  
  468.       if ( ((**hCurDCE).dCtlFlags & dRAMBased) && pCurDrvr )
  469.       {
  470.         pCurDrvr = *( DriverPtr * ) pCurDrvr;
  471.       }
  472.  
  473.       if ( pCurDrvr &&
  474.            EqualString( drvrName, pCurDrvr->drvrName, false, true ) )
  475.       {
  476.         return ~sDrvrNum;
  477.       }
  478.     }
  479.   }
  480.  
  481.   return 0;
  482. }
  483.  
  484.  
  485. -- 
  486. Want some? <slap, thud>                                       csuley@netcom.com
  487. Want some? <slap, thud>                             ChrisSuley@{eworld,aol}.com
  488.  
  489. ---------------------------
  490.  
  491. >From altitude@umich.edu (Alex Tang)
  492. Subject: Is it possible to notify another mac?
  493. Date: 23 Sep 1994 21:09:51 GMT
  494. Organization: University of Michigan
  495.  
  496. Hi folks.  
  497.  
  498. I was wondering if it was possible to pull up a dialog box or alert box on
  499. another mac via either AppleTalk or IP.  
  500.  
  501. Me 'n some friends want to write an app that will (in it's most simple
  502. incarnation) open up an alert box on another mac and give them a piece of
  503. information.  
  504.  
  505. In it's most complicated incarnation, we would really like to be able to
  506. have one mac contact the notification manager on another mac, and run a
  507. program on that mac.
  508.  
  509. This is all presuming we know the AppleTalk node or IP address of the
  510. sending and receiving mac.
  511.  
  512. Thanx
  513. ...alex...
  514.  
  515.  
  516. --
  517.     Alex Tang      |     UM-SNRE   |       UM-ITD/US Consultant II
  518. ALTITUDE@UMICH.EDU |     Student   |    UM-SNRE-NCEET: Systems Admin
  519.   PGP via finger.  | Systems Admin |http://www.snre.umich.edu/users/altitude
  520. This space for rent|Comp.Consut III| An eye for an eye leaves everyone blind.
  521.  
  522. +++++++++++++++++++++++++++
  523.  
  524. >From nick+@pitt.edu ( nick.c )
  525. Date: Fri, 23 Sep 94 20:42:20 GMT
  526. Organization: The Pitt, Chemistry
  527.  
  528. In Article <35vg70$7v6@lastactionhero.rs.itd.umich.edu>, altitude@umich.edu
  529. (Alex Tang) wrote:
  530.  
  531. >I was wondering if it was possible to pull up a dialog box or alert box on
  532. >another mac via either AppleTalk or IP.  
  533. >
  534. >Me 'n some friends want to write an app that will (in it's most simple
  535. >incarnation) open up an alert box on another mac and give them a piece of
  536. >information.  
  537. >
  538. >In it's most complicated incarnation, we would really like to be able to
  539. >have one mac contact the notification manager on another mac, and run a
  540. >program on that mac.
  541.  
  542.  
  543.     Possible and been done.  I remember seeing a notification like
  544.       program on Umich... forget the name... "Broadcast"?.  Dunno.
  545.       Anyway, as I recall you have to have program linking on on the 
  546.       receiving mac, and have to have loaded an extension on the
  547.       receiving mac that takes your message and forwards it to the
  548.       local notification manager.  You could also create an extension
  549.       that sends out apple events, so could launch a local program
  550.       when keyed remotely.  I'd check out NIM:networking for more
  551.       details, luck
  552.  
  553.                                         -- nick
  554.  
  555.  
  556.  
  557.                                     _/   _/  _/  _/_/_/   _/   _/  
  558.      Interet: nick@pitt.edu        _/_/ _/  _/  _/   _/  _/_/_/    
  559.       eWorld: nick                _/ _/_/  _/  _/       _/ _/      
  560.          CIS: 71232,766          _/   _/  _/   _/_/_/  _/   _/     
  561.  
  562.  
  563. +++++++++++++++++++++++++++
  564.  
  565. >From jonasw@lysator.liu.se (Jonas Wallden)
  566. Date: 24 Sep 1994 21:19:28 GMT
  567. Organization: (none)
  568.  
  569. altitude@umich.edu (Alex Tang) writes:
  570.  
  571. >Hi folks.  
  572. >
  573. >I was wondering if it was possible to pull up a dialog box or alert box on
  574. >another mac via either AppleTalk or IP.  
  575. >
  576. >Me 'n some friends want to write an app that will (in it's most simple
  577. >incarnation) open up an alert box on another mac and give them a piece of
  578. >information.  
  579. >
  580. >In it's most complicated incarnation, we would really like to be able to
  581. >have one mac contact the notification manager on another mac, and run a
  582. >program on that mac.
  583. >
  584. >This is all presuming we know the AppleTalk node or IP address of the
  585. >sending and receiving mac.
  586.  
  587. A nice little hack is 'Radiation + Trigger' which can be used to fake
  588. error messages on anoter Mac's screen. Very useful in lab rooms... :-)
  589. It is an INIT that receives messages through the PPC Toolbox and displays
  590. them as Notification Manager alerts.
  591.  
  592. BTW, the default message is 'The radiation shield on your Macintosh has
  593. failed. Please step back 5 feet.' which explains its name... Use with
  594. care on newbies!
  595.  
  596. --
  597. `.`.   Jonas Wallden                    `.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.
  598. `.`.`.   Internet: jonasw@lysator.liu.se  `.`.`.`.`.`.`.`.`.`.`.`.`.`.`.`.
  599. `.`.`.`.   AppleLink: sw1369                `.`.`.`.`.`.`.`.`.`.`.`.`.`.`.
  600.  
  601. ---------------------------
  602.  
  603. >From jlawrie@malibu.sfu.ca (John William Lawrie)
  604. Subject: Memory moving and Inits
  605. Date: 16 Sep 94 17:13:25 GMT
  606. Organization: Simon Fraser University
  607.  
  608. Hi.  I want to have an extension that performs periodic taks.  I have
  609. a skeleton extension that does this already, but the problem is, I
  610. will want to call toolbox routines that will call the memory manager.
  611. Is there a way around this?
  612.  
  613. John@helix.net
  614.  
  615.  
  616. +++++++++++++++++++++++++++
  617.  
  618. >From onyxtech@aol.com (OnyxTech)
  619. Date: 17 Sep 1994 04:26:02 -0400
  620. Organization: America Online, Inc. (1-800-827-6364)
  621.  
  622. In article <jlawrie.779735605@sfu.ca>, jlawrie@malibu.sfu.ca (John William
  623. Lawrie) writes:
  624.  
  625. > Hi.  I want to have an extension that performs periodic
  626. > taks.  I have a skeleton extension that does this already,
  627. > but the problem is, I will want to call toolbox routines
  628. > that will call the memory manager. Is there a way around
  629. > this?
  630.  
  631. It's ok to move memory in a trap patch, but It all depends on what you're
  632. using to trigger your extension code?  If you're installing a time manager
  633. or VBL routine, forget trying to move memory during that code because they
  634. can/will be executed during interupt time and moving memory then is a
  635. strict no no.  If you are triggering your extension code off a trap patch,
  636. them make sure it is a trap patch that can move memory.  Then you're ok. 
  637. If you are triggering off a trap patch that isn't documented as moving
  638. memory, you'd better change your code because you'll eventually get in
  639. trouble. And since I'm not sure what you're patching, better make sure
  640. that what your trap patch calls does not lead to what you're patching. 
  641. Re-entrant city unless you handle it correctly.
  642.  
  643. dEVoN
  644.  
  645. +++++++++++++++++++++++++++
  646.  
  647. >From jcornish@netcom.com (Jud Cornish)
  648. Date: Sun, 18 Sep 1994 08:32:34 GMT
  649. Organization: NETCOM On-line Communication Services (408 261-4700 guest)
  650.  
  651. To perform periodic tasks that may move/purge memory:
  652.  
  653. A simple solution is to patch a trap (or several) that are known to
  654. move/purge memory and are commonly called.  I did some "OS Profiling" of
  655. my own to identify a set of traps that I could patch that would give
  656. frequent time to such a task.  The other objective was to get time when
  657. apps, the OS or the Toolbox is in a tight loop such as while tracking a
  658. close box.  If you patch any one trap, there will be times when you can go
  659. for quite some time without an opportunity to snag some time.  I shouldn't
  660. go into the details, but with some common sense (and a little time with
  661. macsbug) one can pick a pretty good set of traps.  All this is only
  662. necessary if you have a really critical time based task.  Not critical in
  663. accuracy, but in avoiding long pauses.  All this is necessary because of
  664. the way "multi-tasking" is done on the mac.  Processes are only granted
  665. time when others share it. 
  666.  
  667. Another option would be to install a driver which requested periodic time. 
  668. This is actually harder than just patching _SystemTask, which I believe
  669. would function identically. 
  670.  
  671. Yet another option is to pre-allocate some memory with your INIT, then eat
  672. it up as you need it.  In a sense, depending on the complexity of your
  673. memory use, you can just start filling up a simple buffer with data, or
  674. you could make your own sub memory manager!!! 
  675.  
  676. A hybrid solution is to perform periodic tasks via the time manager, with
  677. accuracy and nearly guaranteed time, then when you fill up your buffer (or
  678. get sufficiently close to it), you set a flag which a _SystemTask patch
  679. can use to know when to grow the buffer.  You would need to temporarily
  680. suspend your use of the buffer while the patch is growing (and probably
  681. moving) it.  This can be done with another flag manipulated just before
  682. and after the SetHandleSize. The periodic task would always make sure this
  683. flag was clear before dereferencing the handle and using the buffer. 
  684.  
  685. I have little idea what your actual needs are but I hope that this
  686. discussion is helpful.  Hopefully, a simple patch will suffice.  As far as
  687. I have seen (68k sys 7.5), the OS still calls _SystemTask periodically. 
  688. If this is indeed the case, it is a good target as other processes will
  689. expect to share time when this happens (usually from a _waitNextEvent
  690. call). 
  691.  
  692. Any comments on my comments would be appreciated.
  693.  
  694. Erik J. Rogers
  695.  
  696. +++++++++++++++++++++++++++
  697.  
  698. >From resnick@uiuc.edu (Pete Resnick)
  699. Date: Sun, 18 Sep 1994 13:00:37 -0500
  700. Organization: University of Illinois at Urbana-Champaign
  701.  
  702. In article <jlawrie.779735605@sfu.ca>, jlawrie@malibu.sfu.ca (John William
  703. Lawrie) wrote:
  704.  
  705. > Hi.  I want to have an extension that performs periodic taks.  I have
  706. > a skeleton extension that does this already, but the problem is, I
  707. > will want to call toolbox routines that will call the memory manager.
  708. > Is there a way around this?
  709.  
  710. My personal favorite is to use a Time Manager task to do the periodic
  711. part, and have the completion proc for the Time Manager routine post a
  712. Notification Manager request that has all the fields except nmResp
  713. cleared. In the notification response, you can do whatever you want to do
  714. since it is Memory Manager safe.
  715.  
  716. pr
  717. -- 
  718. Pete Resnick    (...so what is a mojo, and why would one be rising?)
  719. Doctoral Student - Philosophy Department, Gregory Hall, UIUC
  720. System manager - Cognitive Science Group, Beckman Institute, UIUC
  721. Internet: resnick@uiuc.edu
  722.  
  723. +++++++++++++++++++++++++++
  724.  
  725. >From Jaeger@fquest.com (Brian Stern)
  726. Date: 19 Sep 1994 05:03:25 GMT
  727. Organization: The University of Texas at Austin, Austin, Texas
  728.  
  729. In article <jlawrie.779735605@sfu.ca>, jlawrie@malibu.sfu.ca (John William
  730. Lawrie) wrote:
  731.  
  732. < Hi.  I want to have an extension that performs periodic taks.  I have
  733. < a skeleton extension that does this already, but the problem is, I
  734. < will want to call toolbox routines that will call the memory manager.
  735. < Is there a way around this?
  736. < John@helix.net
  737.  
  738. A jGNEFilter is a simple way to get periodic time and you can move memory
  739. if you need to.  The only problem is that you aren't guaranteed that it
  740. will be called frequently.
  741.  
  742. -- 
  743. Brian  Stern  :-{)}
  744. Jaeger@fquest.com
  745.  
  746. +++++++++++++++++++++++++++
  747.  
  748. >From blob@apple.com (Brian Bechtel)
  749. Date: 24 Sep 1994 14:39:56 -0700
  750. Organization: Apple Computer, Inc., Cupertino, California
  751.  
  752. Jaeger@fquest.com (Brian Stern) writes:
  753.  
  754. >In article <jlawrie.779735605@sfu.ca>, jlawrie@malibu.sfu.ca (John William
  755. >Lawrie) wrote:
  756.  
  757. >< Hi.  I want to have an extension that performs periodic taks.  I have
  758. >< a skeleton extension that does this already, but the problem is, I
  759. >< will want to call toolbox routines that will call the memory manager.
  760. >< Is there a way around this?
  761.  
  762. >A jGNEFilter is a simple way to get periodic time and you can move memory
  763. >if you need to.  The only problem is that you aren't guaranteed that it
  764. >will be called frequently.
  765.  
  766. Even better is a faceless background application.  You can call any
  767. toolbox routine that doesn't provide a user interface. You get time like
  768. any other application.
  769.  
  770. --Brian Bechtel     blob@apple.com     "My opinion, not Apple's"
  771.  
  772. ---------------------------
  773.  
  774. >From ldo@waikato.ac.nz (Lawrence D'Oliveiro, Waikato University)
  775. Subject: Self-disposing notification crashes
  776. Date: 16 Sep 94 16:35:09 +1200
  777. Organization: University of Waikato, Hamilton, New Zealand
  778.  
  779. I'm working on this MPW tool that sends a PostScript stream to a printer via
  780. PAP, and displays whatever the printer sends back. It loads the PDEF 10 code
  781. from the LaserWriter driver (I know, I know, but this is for in-house use,
  782. and I have ways of keeping it working under QuickDraw GX ;-)). However,
  783. I didn't like the PAPStatus call that that library provides, as it's
  784. synchronous, and tends to hang for several seconds if the printer goes away.
  785.  
  786. So I tried implementing my own version of PAPStatus. My version allocates
  787. a temporary block in the heap, which is used to contain the context for the
  788. call, including pointers to the user's data areas. Once the query starts,
  789. everything runs at interrupt time as a sequence of chained completion routines
  790. from then on, except of course for the last bit of code that gets rid of the
  791. temporary block. This code runs as a notification routine, so that it's safe
  792. for it to make Memory Manager calls.
  793.  
  794. The notification code is actually copied into the temporary block, and executes
  795. out of there. I did this as part of a strategy for dealing cleanly with aborting
  796. execution of the tool, though admittedly my handling of this is not complete
  797. as yet.
  798.  
  799. Anyway, this notification routine is very small, and is written in assembler.
  800. Here it is in its entirety:
  801.  
  802.     move.l    4(sp), a0
  803.     _NMRemove
  804.     move.l    NMRec.nmRefCon(a0), a0
  805.     _DisposePtr
  806.     move.l    (sp)+, (sp)
  807.     rts
  808.  
  809. Note that the DisposePtr call is disposing of the block containing the code
  810. (and the notification record) itself! However, I have stepped through this
  811. code with MacsBug, and watched it successfully return from DisposePtr and
  812. execute those last two instructions just fine.
  813.  
  814. Basically, the problem is, my tool tends to crash, but only the second time
  815. it runs. The first time is always fine: I can send a large multi-page print
  816. job to the printer (with lots of status queries throughout), or I can send
  817. a small one-line query, and it will always work. However, the second time I
  818. try invoking my tool, it will crash.
  819.  
  820. I finally narrowed it down to one thing: the DisposePtr call in the
  821. notification routine, above. If I no-op out the dispose call (causing a
  822. resultant accumulation of allocated memory blocks in MPW's heap), I can run the
  823. tool multiple times just fine.
  824.  
  825. Anybody got any ideas as to why this can't work?
  826.  
  827. Thanks for any help.
  828.  
  829. Lawrence D'Oliveiro                       fone: +64-7-856-2889
  830. Info & Tech Services Division              fax: +64-7-838-4066
  831. University of Waikato            electric mail: ldo@waikato.ac.nz
  832. Hamilton, New Zealand    37^ 47' 26" S, 175^ 19' 7" E, GMT+12:00
  833.  
  834. +++++++++++++++++++++++++++
  835.  
  836. >From pottier@fregate.ens.fr (Francois Pottier)
  837. Date: 16 Sep 1994 11:28:28 GMT
  838. Organization: Ecole Normale Superieure, PARIS, France
  839.  
  840. In article <1994Sep16.163509.33240@waikato.ac.nz>,
  841. Lawrence D'Oliveiro, Waikato University <ldo@waikato.ac.nz> wrote:
  842. >
  843. >Anyway, this notification routine is very small, and is written in assembler.
  844. >Here it is in its entirety:
  845. >
  846. >    move.l    4(sp), a0
  847. >    _NMRemove
  848. >    move.l    NMRec.nmRefCon(a0), a0
  849. >    _DisposePtr
  850. >    move.l    (sp)+, (sp)
  851. >    rts
  852. >
  853. >Note that the DisposePtr call is disposing of the block containing the code
  854.  
  855. I'm interested in this problem too. My notification routine looks exactly
  856. the same way. It works perfectly, but I'm concerned that it might break in
  857. the future.
  858.  
  859. Apple has warned against this sort of thing; once the block is freed, you
  860. can't make any assumptions about its contents (so you can't execute code in
  861. it). This makes sense; in a preemptive multitasking system, the block could
  862. very well by allocated by another process before you have time to rts out of
  863. it.
  864.  
  865. However, I don't see any other way of disposing properly of the Notification
  866. Record. If you want your notification to appear after your normal code is
  867. dead (INITs need to do that), then you must copy the response proc into a
  868. standalone block in the System heap. And if you want to clean up properly,
  869. you should release this block after it's been used. So there appears to be
  870. no way to do the Right Thing here.
  871.  
  872. I'd be interested in comments...
  873.  
  874.  
  875.  
  876.  
  877. -- 
  878. Francois Pottier                                            pottier@dmi.ens.fr
  879. - ----------------------------------------------------------------------------
  880. Check my WWW page at http://acacia.ens.fr:8080/home/pottier/index.html ...
  881.  
  882. +++++++++++++++++++++++++++
  883.  
  884. >From Jaeger@fquest.com (Brian Stern)
  885. Date: 16 Sep 1994 15:48:28 GMT
  886. Organization: The University of Texas at Austin, Austin, Texas
  887.  
  888. In article <35bvgs$h87@nef.ens.fr>, pottier@fregate.ens.fr (Francois
  889. Pottier) wrote:
  890.  
  891.  
  892. < However, I don't see any other way of disposing properly of the Notification
  893. < Record. If you want your notification to appear after your normal code is
  894. < dead (INITs need to do that), then you must copy the response proc into a
  895. < standalone block in the System heap. And if you want to clean up properly,
  896. < you should release this block after it's been used. So there appears to be
  897. < no way to do the Right Thing here.
  898. < I'd be interested in comments...
  899. < -- 
  900. < Francois Pottier                                            pottier@dmi.ens.fr
  901. < ------------------------------------------------------------------------------
  902. < Check my WWW page at http://acacia.ens.fr:8080/home/pottier/index.html ...
  903.  
  904. If you check out Dair Grant's Init Shell package, at an ftp site near you,
  905. you'll find some code that gets around this problem.  It works by poking
  906. several instructions into ToolScratch, including the disposePtr, and then
  907. jumping to those instructions.  I believe this is based on some code that
  908. was in the old usenet mac programmers guide.
  909.  
  910. Cheers,
  911.  
  912. -- 
  913. Brian  Stern  :-{)}
  914. Jaeger@fquest.com
  915.  
  916. +++++++++++++++++++++++++++
  917.  
  918. >From resnick@uiuc.edu (Pete Resnick)
  919. Date: Fri, 16 Sep 1994 15:00:26 -0500
  920. Organization: University of Illinois at Urbana-Champaign
  921.  
  922. In article <1994Sep16.163509.33240@waikato.ac.nz>, ldo@waikato.ac.nz
  923. (Lawrence D'Oliveiro, Waikato University) wrote:
  924.  
  925. > Anyway, this notification routine is very small, and is written in assembler.
  926. > Here it is in its entirety:
  927. >         move.l  4(sp), a0
  928. >         _NMRemove
  929. >         move.l  NMRec.nmRefCon(a0), a0
  930. >         _DisposePtr
  931. >         move.l  (sp)+, (sp)
  932. >         rts
  933. > Note that the DisposePtr call is disposing of the block containing the code
  934. > (and the notification record) itself! However, I have stepped through this
  935. > code with MacsBug, and watched it successfully return from DisposePtr and
  936. > execute those last two instructions just fine.
  937.  
  938. Yow!! This would be bad since you can't depend on when that memory is
  939. going to be overwritten, and for you, it's happening in the call to
  940. _DisposePtr. There are two ways around this:
  941.  
  942. On anything better than a 68010 (which is all Macs except for the classic
  943. one) there is a wonderful little instruction: RTD. That instruction
  944. returns, but also simultaneously deallocates space on the stack. So, what
  945. I do is call _NMRemove (and whatever other cleanup I want to do) and then
  946. move the _DisposePtr and an RTD instruction to the stack:
  947.  
  948.         move.l  4(sp),a0                ; Move the NMRec
  949.         _NMRemove                       ; Remove it
  950.         move.l  NMRec.nmRefCon(a0),a1   ; Address of code+NMRec into A1
  951.         movea.l (sp)+,a0                ; Return address into A0
  952.         move.l  #$4E740006,-(sp)        ; RTD #$0006
  953.         move.w  #$a01f,-(sp)            ; _DisposePtr
  954.         move.l  a0,-(sp)                ; Return address back onto stack
  955.         pea     4(sp)                   ; Address of _DisposePtr on stack
  956.         moveq   #$1,d0
  957.         _HWPriv                         ; Flush the cache
  958.         movea.l a1,a0                   ; Address to dispose
  959.         rts                             ; Return to _DisposePtr on stack
  960.  
  961. So the stack (before the final RTS) looks like:
  962.  
  963.         +0000   <sp + 8>
  964.         +0004   <old return address>
  965.         +0008   _DisposePtr
  966.         +000A   RTD #$0006
  967.         .....Rest of stack
  968.  
  969. So when that last RTS executes, it rips the address of sp+8 off of the
  970. stack and jumps to it. The _DisposePtr disposes what's in A0 (the code and
  971. the NMRec), then the RTD takes the old return address off the stack, moves
  972. the stack pointer 6 bytes (past the _DisposePtr and the RTD #$0006), and
  973. jumps to the return address. Frightening, eh?
  974.  
  975. On the old 68000, you don't have the RTD instruction (nor an instruction
  976. cache), but life is generally a good deal simpler: There is a low memory
  977. global called "ToolScratch", which is an 8-byte scratch area. It stays
  978. constant across the call to _DisposePtr, so what you can do instead is:
  979.  
  980.         move.l  4(sp),a1                ; Move the NMRec
  981.         move.l  (sp)+,(sp)              ; Move the return address into place
  982.         _NMRemove                       ; Remove it
  983.         move.l  NMRec.nmRefCon(a1),a0   ; Address of code+NMRec into A0
  984.         movea.w #ToolScratch,a1         ; Address of the LM global
  985.         move.l  a1,-(sp)                ; Put the address onto the stack
  986.         move.l  #$a01f4E75,(a1)         ; _DisposePtr / RTS
  987.         rts
  988.  
  989. So now the stack looks like:
  990.  
  991.         +0000   <address of ToolScratch>
  992.         +0004   <old return address>
  993.         .....Rest of stack
  994.  
  995. And ToolScratch has in it:
  996.  
  997.         _DisposePtr
  998.         RTS
  999.  
  1000. This has worked perfectly for me. Executing code on the stack is pretty
  1001. wierd, but it works just great.
  1002.  
  1003. pr
  1004. -- 
  1005. Pete Resnick    (...so what is a mojo, and why would one be rising?)
  1006. Doctoral Student - Philosophy Department, Gregory Hall, UIUC
  1007. System manager - Cognitive Science Group, Beckman Institute, UIUC
  1008. Internet: resnick@uiuc.edu
  1009.  
  1010. +++++++++++++++++++++++++++
  1011.  
  1012. >From jberry@teleport.com (James D. Berry)
  1013. Date: Fri, 16 Sep 1994 13:39:16 -0700
  1014. Organization: Consultant
  1015.  
  1016. In article <1994Sep16.163509.33240@waikato.ac.nz>, ldo@waikato.ac.nz
  1017. (Lawrence D'Oliveiro, Waikato University) wrote:
  1018.  
  1019. > Anyway, this notification routine is very small, and is written in assembler.
  1020. > Here it is in its entirety:
  1021. >         move.l  4(sp), a0
  1022. >         _NMRemove
  1023. >         move.l  NMRec.nmRefCon(a0), a0
  1024. >         _DisposePtr
  1025. >         move.l  (sp)+, (sp)
  1026. >         rts
  1027. > Note that the DisposePtr call is disposing of the block containing the code
  1028. > (and the notification record) itself! However, I have stepped through this
  1029. > code with MacsBug, and watched it successfully return from DisposePtr and
  1030. > execute those last two instructions just fine.
  1031.  
  1032. I can't see the rest of your code, but it strikes me that if for some
  1033. reason the NMRemove call is being passed an incorrect value, then you'd be
  1034. leaving a bogus link in the NMQueue (because you've deleted the code it's
  1035. pointing to) which would cause a crash on the next invokation.
  1036.  
  1037. I'm a purest at heart, and also don't like the fact that you're executing
  1038. two instructions out of a block that's been disposed. The Modern Memory
  1039. Manager, in fact, has a debug mode that'll trash blocks as they're
  1040. disposed, which should break your code.
  1041.  
  1042. I use the following code to (cleanly?) cleanup following a notification.
  1043. Note that it assumes the NMRec and supporting code are all allocated into
  1044. a single heap block. It hasn't yet (!!) managed to break the 68K emulator,
  1045. though it seems a good target to :-()  Now if Apple would just give us a
  1046. few NM flags that specify a block to be deleted following notification!
  1047.  
  1048. ;------------------------------------------------------------
  1049. ;  pascal void NotifyProc(NMRecPtr pRec)
  1050. ;
  1051. ;  The notify proc. Its sole purpose in life is to
  1052. ;  clean-up following the notification manager.
  1053. ;------------------------------------------------------------
  1054. NotifyProc        proc
  1055.                machine  mc68020
  1056.                entry NotifyProcLen
  1057.  
  1058.                subq     #2,sp                ; Extra space 8 bytes --> 10 bytes
  1059.                move.l   2(sp),-(sp)          ; Move Return address
  1060.                move.l   10(sp),-(sp)         ; Move NMRecPtr
  1061.                
  1062.                lea      @StackCodeEnd,a1     ; Move our _DisposePtr code
  1063. onto stack
  1064.                lea      14(sp),a0            ; so that we can suicide cleanly!
  1065.                move.l   -(a1),-(a0)          ; rtd #x
  1066.                move.w   -(a1),-(a0)          ; _DisposePtr
  1067.                moveq    #6,d0                ; Length of the code
  1068.                move.l   d0,a1                ; into a1
  1069.                
  1070.                _FlushCodeCacheRange          ; Flush the caches where we
  1071. wrote code
  1072.                
  1073.                move.l   a0,a1                ; Pointer to our cleanup code
  1074. on stack
  1075.                move.l   (sp)+,a0             ; Get NMRecPtr
  1076.                
  1077.                _NMRemove                     ; Unqueue the NMRec
  1078.                
  1079.                jmp      (a1)                 ; Call cleanup code to
  1080. dispose the block we're
  1081.                                              ; currently executing out of
  1082.                                           
  1083.                ;  This code will be moved onto the stack
  1084.                ;  before it is executed, so that we don't
  1085.                ;  execute code out of a deallocated block
  1086.                
  1087.                _DisposePtr                   ; Dispose the
  1088. NMRec/code/string block
  1089.                rtd      #6                   ; Return to caller,
  1090. deallocating this code!
  1091. @StackCodeEnd
  1092.  
  1093. NotifyProcLen  dc.l  *-NotifyProc            ; Length of our notification proc
  1094.  
  1095.                endp
  1096.  
  1097. -- 
  1098. James Berry
  1099. jberry@teleport.com
  1100.  
  1101. +++++++++++++++++++++++++++
  1102.  
  1103. >From Bruce@hoult.actrix.gen.nz (Bruce Hoult)
  1104. Date: Sat, 17 Sep 1994 14:50:34 +1200 (NZST)
  1105. Organization: (none)
  1106.  
  1107. ldo@waikato.ac.nz (Lawrence D'Oliveiro, Waikato University) writes:
  1108. > I'm working on this MPW tool that sends a PostScript stream to a printer via
  1109. > PAP, and displays whatever the printer sends back.
  1110.  
  1111. Heh.  I turned your downloader XCMDs into an MPW Tool only about -- what? --
  1112. seven years ago.
  1113.  
  1114.  
  1115. > It loads the PDEF 10 code
  1116. > from the LaserWriter driver (I know, I know, but this is for in-house use
  1117. > and I have ways of keeping it working under QuickDraw GX ;-)).
  1118.  
  1119. Hmm.  Looks as if I'm going to need an update :-(
  1120.  
  1121.  
  1122. > I finally narrowed it down to one thing: the DisposePtr call in the
  1123. > notification routine, above. If I no-op out the dispose call (causing a
  1124. > resultant accumulation of allocated memory blocks in MPW's heap), I can run the
  1125. > tool multiple times just fine.
  1126. > Anybody got any ideas as to why this can't work?
  1127.  
  1128. It's not going to like the Modern Memory Manager, which stores some info
  1129. inside your data block as soon as you dispose it.
  1130.  
  1131. OTOH, if the last two instructions are surviving then it's hard to see what's
  1132. going wrong.  You *are* allocating a new block and a new copy of the code
  1133. each time you use it, right?
  1134.  
  1135. Might you not be better to allocate a small block the first time you run
  1136. and just leave it alive?  And use Gestalt or something to find it each time?
  1137.  
  1138. -- Bruce
  1139.  
  1140. +++++++++++++++++++++++++++
  1141.  
  1142. >From ludis@netcom.com (Ludis Langens)
  1143. Date: Sat, 17 Sep 1994 23:28:18 GMT
  1144. Organization: Netcom Online Communications Services (408-241-9760 login: guest)
  1145.  
  1146. In article <35bvgs$h87@nef.ens.fr> pottier@fregate.ens.fr (Francois Pottier) writes:
  1147. >In article <1994Sep16.163509.33240@waikato.ac.nz>,
  1148. >Lawrence D'Oliveiro, Waikato University <ldo@waikato.ac.nz> wrote:
  1149. >>
  1150. >>Anyway, this notification routine is very small, and is written in assembler.
  1151. >>Here it is in its entirety:
  1152. >>
  1153. >>    move.l    4(sp), a0
  1154. >>    _NMRemove
  1155. >>    move.l    NMRec.nmRefCon(a0), a0
  1156. >>    _DisposePtr
  1157. >>    move.l    (sp)+, (sp)
  1158. >>    rts
  1159. >>
  1160. >>Note that the DisposePtr call is disposing of the block containing the code
  1161. >
  1162. >I'm interested in this problem too. My notification routine looks exactly
  1163. >the same way. It works perfectly, but I'm concerned that it might break in
  1164. >the future.
  1165. >
  1166. >Apple has warned against this sort of thing; once the block is freed, you
  1167. >can't make any assumptions about its contents (so you can't execute code in
  1168. >it). This makes sense; in a preemptive multitasking system, the block could
  1169. >very well by allocated by another process before you have time to rts out of
  1170. >it.
  1171. >
  1172. >However, I don't see any other way of disposing properly of the Notification
  1173. >Record. If you want your notification to appear after your normal code is
  1174. >dead (INITs need to do that), then you must copy the response proc into a
  1175. >standalone block in the System heap. And if you want to clean up properly,
  1176. >you should release this block after it's been used. So there appears to be
  1177. >no way to do the Right Thing here.
  1178.  
  1179. To dispose the memory block out of which you are executing, try this:
  1180.  
  1181. BlockStart EQU *
  1182.  
  1183.         ...
  1184.         MOVEQ   #$1F,D0           ;Trap number of DisposPtr
  1185.         _GetTrapAddress OS
  1186.         MOVE.L  A0,A1
  1187.         LEA     BlockStart(PC),A0
  1188.         JMP     (A1)
  1189.  
  1190. Use this code as the very last thing you execute.  Make sure you have
  1191. removed any parameters from the stack (so that an RTS can return to
  1192. your caller.)  The JMP (A1) goes to the memory manager directly,
  1193. bypassing the trap dispatcher.  This means that registers D0-D2/A0-A1
  1194. may be changed.  Once DisposPtr has freed the block, it will return
  1195. (directly) to your caller.  When you link your code fragment, make sure
  1196. that BlockStart is at offset 0 in the memory block.  This same trick
  1197. can be also be used with handles by adding a RecoverHandle (and getting
  1198. the address of DisposHandle.)
  1199.  
  1200. Ludis Langens
  1201. ludis@netcom.com
  1202.  
  1203. +++++++++++++++++++++++++++
  1204.  
  1205. >From ldo@waikato.ac.nz (Lawrence D'Oliveiro, Waikato University)
  1206. Date: 19 Sep 94 14:24:01 +1200
  1207. Organization: University of Waikato, Hamilton, New Zealand
  1208.  
  1209. In article <jberry-1609941339160001@ip-ce.teleport.com>, jberry@teleport.com (James D. Berry) writes:
  1210. > In article <1994Sep16.163509.33240@waikato.ac.nz>, ldo@waikato.ac.nz
  1211. > (Lawrence D'Oliveiro, Waikato University) wrote:
  1212. >
  1213. >> Anyway, this notification routine is very small, and is written in assembler.
  1214. >> Here it is in its entirety:
  1215. >>
  1216. >>         move.l  4(sp), a0
  1217. >>         _NMRemove
  1218. >>         move.l  NMRec.nmRefCon(a0), a0
  1219. >>         _DisposePtr
  1220. >>         move.l  (sp)+, (sp)
  1221. >>         rts
  1222. >>
  1223. >> Note that the DisposePtr call is disposing of the block containing the code
  1224. >> (and the notification record) itself! However, I have stepped through this
  1225. >> code with MacsBug, and watched it successfully return from DisposePtr and
  1226. >> execute those last two instructions just fine.
  1227. >
  1228. > I can't see the rest of your code, but it strikes me that if for some
  1229. > reason the NMRemove call is being passed an incorrect value, then you'd be
  1230. > leaving a bogus link in the NMQueue (because you've deleted the code it's
  1231. > pointing to) which would cause a crash on the next invokation.
  1232.  
  1233. The NMRec address must be correct, because its nmRefCon contains the pointer
  1234. to the entire block, which is indeed being correctly disposed. (Like I said,
  1235. I checked this with MacsBug.)
  1236.  
  1237. > I'm a purest at heart, and also don't like the fact that you're executing
  1238. > two instructions out of a block that's been disposed. The Modern Memory
  1239. > Manager, in fact, has a debug mode that'll trash blocks as they're
  1240. > disposed, which should break your code.
  1241.  
  1242. That must be the only memory manager in the world that does that...
  1243.  
  1244. Lawrence D'Oliveiro                       fone: +64-7-856-2889
  1245. Info & Tech Services Division              fax: +64-7-838-4066
  1246. University of Waikato            electric mail: ldo@waikato.ac.nz
  1247. Hamilton, New Zealand    37^ 47' 26" S, 175^ 19' 7" E, GMT+12:00
  1248. "Icons are the droppings located at the top and sides of the Windows display."
  1249.                        -- reported in PC Magazine
  1250.  
  1251. +++++++++++++++++++++++++++
  1252.  
  1253. >From jan3@po.cwru.edu (James A. Nauer)
  1254. Date: Mon, 19 Sep 1994 17:18:49 -0400
  1255. Organization: Case Western Reserve University
  1256.  
  1257. In article <1994Sep19.142402.33297@waikato.ac.nz>, ldo@waikato.ac.nz
  1258. (Lawrence D'Oliveiro, Waikato University) wrote:
  1259.  
  1260. > In article <jberry-1609941339160001@ip-ce.teleport.com>,
  1261. jberry@teleport.com (James D. Berry) writes:
  1262. > >
  1263. > > I'm a purest at heart, and also don't like the fact that you're executing
  1264. > > two instructions out of a block that's been disposed. The Modern Memory
  1265. > > Manager, in fact, has a debug mode that'll trash blocks as they're
  1266. > > disposed, which should break your code.
  1267. > That must be the only memory manager in the world that does that...
  1268.  
  1269. Not true.  I have an anti-virus TSR on my PC which, among other things,
  1270. patches the (feeble) DOS memory management routines to zero out all freed
  1271. blocks before returning.  Naturally, I also have a couple of programs that
  1272. fail because they think they can get away with using a few bytes of data
  1273. in a block _after_ freeing it :-(.
  1274. -- 
  1275. James A. Nauer             | "I shall not yield one whit of maturity,
  1276. Library Information        | not grace, not respectibility, to the 
  1277. Technologies               | passing of time. I declare that I shall
  1278. Case Western Reserve Univ. | forever be, if not a child, certainly
  1279. (216) 368-MACS  (368-6227) | childish"  --Kennet Shardik
  1280.  
  1281. +++++++++++++++++++++++++++
  1282.  
  1283. >From h+@nada.kth.se (Jon W{tte)
  1284. Date: Tue, 20 Sep 1994 10:36:19 +0200
  1285. Organization: Royal Institute of Something or other
  1286.  
  1287. In article <1994Sep19.142402.33297@waikato.ac.nz>,
  1288. ldo@waikato.ac.nz (Lawrence D'Oliveiro, Waikato University) wrote:
  1289.  
  1290. >> two instructions out of a block that's been disposed. The Modern Memory
  1291. >> Manager, in fact, has a debug mode that'll trash blocks as they're
  1292. >> disposed, which should break your code.
  1293. >
  1294. >That must be the only memory manager in the world that does that...
  1295.  
  1296. Not at all; several malloc() implementations IMMEDIATELY writes 
  1297. data into the block being disposed, like a pointer in a linked 
  1298. list of free blocks, or something like that.
  1299.  
  1300. Using a block after disposing it is BAD BAD BAD. The 
  1301. Cleanup/GetTrapAddress/Jump solution is the only clean one, but 
  1302. depends on the fact that DisposePtr uses register calling 
  1303. conventions.
  1304.  
  1305. Cheers,
  1306.  
  1307.                 / h+
  1308.  
  1309.  
  1310. --
  1311.   Jon W‰tte (h+@nada.kth.se), Hagagatan 1, 113 48 Stockholm, Sweden
  1312.  V}ga v{gra nonkonformism!
  1313.  
  1314.  
  1315. +++++++++++++++++++++++++++
  1316.  
  1317. >From fixer@faxcsl.dcrt.nih.gov (Chris Biscottimeister Tate)
  1318. Date: Tue, 20 Sep 1994 18:44:17 GMT
  1319. Organization: DCRT, NIH, Bethesda, MD
  1320.  
  1321. In article <1994Sep19.142402.33297@waikato.ac.nz>, ldo@waikato.ac.nz (Lawrence D'Oliveiro, Waikato University) writes:
  1322. >In article <jberry-1609941339160001@ip-ce.teleport.com>, jberry@teleport.com (James D. Berry) writes:
  1323. >>
  1324. >> I'm a purist at heart, and also don't like the fact that you're executing
  1325. >> two instructions out of a block that's been disposed. The Modern Memory
  1326. >> Manager, in fact, has a debug mode that'll trash blocks as they're
  1327. >> disposed, which should break your code.
  1328. >
  1329. >That must be the only memory manager in the world that does that...
  1330.  
  1331. I seem to recall running into some odd situations in which the system was
  1332. writing into unallocated heap memory for some reason.  Quickdraw, maybe?
  1333.  
  1334. (I would think that executing out of a just-deallocated block is pretty
  1335. much a recipe for disaster - certainly in a preemptive-multitasking world
  1336. you're doomed if you do it, barring some IMHO unwarranted privileges being
  1337. granted to your code...)
  1338.  
  1339. - ------------------------------------------------------------------
  1340. Christopher Tate           | "Apple Guide makes Windows' help engine
  1341. MSD, Inc.                  |  look like a quadruple amputee."
  1342. fixer@faxcsl.dcrt.nih.gov  |      -- Pete Gontier (gurgle@dnai.com)
  1343.  
  1344. +++++++++++++++++++++++++++
  1345.  
  1346. >From rang@winternet.com (Anton Rang)
  1347. Date: 21 Sep 1994 01:06:37 GMT
  1348. Organization: Trillium Research, Inc.
  1349.  
  1350. In article <9668AAA46BA3.6ED60@klkmac018.nada.kth.se> h+@nada.kth.se (Jon W{tte) writes:
  1351. >Using a block after disposing it is BAD BAD BAD. The 
  1352. >Cleanup/GetTrapAddress/Jump solution is the only clean one, but 
  1353. >depends on the fact that DisposePtr uses register calling 
  1354. >conventions.
  1355.  
  1356.   Actually, you're fine with Pascal calling conventions, too, since
  1357. the callee is responsible for cleaning up the stack.  It's only if you
  1358. are trying to use C calling conventions that you'll have problems with
  1359. exiting via a call to another routine.
  1360. --
  1361. Anton Rang (rang@winternet.com)
  1362.  
  1363. +++++++++++++++++++++++++++
  1364.  
  1365. >From Bruce@hoult.actrix.gen.nz (Bruce Hoult)
  1366. Date: Wed, 21 Sep 1994 14:48:10 +1200 (NZST)
  1367. Organization: (none)
  1368.  
  1369. resnick@uiuc.edu (Pete Resnick) writes:
  1370. > On anything better than a 68010 (which is all Macs except for the classic
  1371. > one) there is a wonderful little instruction: RTD. That instruction
  1372. > returns, but also simultaneously deallocates space on the stack. So, what
  1373. > I do is call _NMRemove (and whatever other cleanup I want to do) and then
  1374. > move the _DisposePtr and an RTD instruction to the stack:
  1375.  
  1376. Arrrrggghhh!!!
  1377.  
  1378. There are a *lot* of PowerBook 100's out there, filled to the gills with
  1379. RAM, and with a long useful life ahead of them still -- I expect to be
  1380. using mine for years yet, even though I've got a PowerMac as my main
  1381. machine.
  1382.  
  1383. In case you didn't realise, the PB100 uses an original 68000 chip.
  1384.  
  1385. -- Bruce
  1386.  
  1387. +++++++++++++++++++++++++++
  1388.  
  1389. >From ludis@netcom.com (Ludis Langens)
  1390. Date: Fri, 23 Sep 1994 21:25:04 GMT
  1391. Organization: Netcom Online Communications Services (408-241-9760 login: guest)
  1392.  
  1393. In article <9668AAA46BA3.6ED60@klkmac018.nada.kth.se> h+@nada.kth.se (Jon W{tte) writes:
  1394. >Using a block after disposing it is BAD BAD BAD. The 
  1395. >Cleanup/GetTrapAddress/Jump solution is the only clean one, but 
  1396. >depends on the fact that DisposePtr uses register calling 
  1397. >conventions.
  1398.  
  1399. The Cleanup/GetTrapAddress/Jump solution does not depend upon its target
  1400. trap using register calling conventions.  A Pascal style trap can also be
  1401. called this way - just rearrange the stack appropriately.  What it does
  1402. depend upon is the register preservation and stack usage of the trap you
  1403. are chaining to.  It could not be used to chain to a C style function
  1404. or to anything that trashes registers which your function must preserve.
  1405.  
  1406. If you need to chain to a toolbox trap, the GetTrapAddress step can be
  1407. omitted by using a trap with the Auto-pop bit set.  This is a very
  1408. 'official' way of jumping to a trap.  (Years ago I used this trick
  1409. to create code segments that self UnloadSeg-ed themselves upon returning
  1410. to their caller.)
  1411.  
  1412. Ludis Langens
  1413. ludis@netcom.com
  1414.  
  1415. ---------------------------
  1416.  
  1417. >From fairgate@vespucci.iquest.com (Fairgate Technologies)
  1418. Subject: [CWWWW] PowerPlant Tour document available
  1419. Date: 23 Sep 1994 15:53:13 -0500
  1420. Organization: interQuest -- Fuel for the Mind
  1421.  
  1422. Thanks to Marc Paquette of Metrowerks, there's now a PowerPlant Tour
  1423. document on CWWWW, along with some other supporting PowerPlant
  1424. material.
  1425.  
  1426. For those of you who know what CWWWW is, these new goodies are
  1427. available on the PowerPlant Central
  1428. (http://www.iquest.com/~fairgate/cw/pplant.html) page.
  1429.  
  1430. If you haven't visited CWWWW yet, come on down! CWWWW is the official
  1431. CodeWarrior World-Wide Web site. IMNSHO there's quite a bit of useful
  1432. information there, especially for the relatively undocumented
  1433. PowerPlant class library. 
  1434.  
  1435. Point your WWW browser at http://www.iquest.com/~fairgate.
  1436.  
  1437. Cheers,
  1438. -Paul
  1439.  
  1440. [ If you don't get a reply from me with 48hrs, please resend your message.
  1441.   The Mail Gods are displeased; incoming mail is sometimes silently dropped. ]
  1442.  
  1443.  
  1444. -- 
  1445.  Paul Robichaux       Fairgate Technologies         paul@fairgate.com
  1446.       Fairgate Technologies does custom Mac development.
  1447.   Visit the CodeWarrior WWW page at http://www.iquest.com/~fairgate.
  1448.  
  1449. ---------------------------
  1450.  
  1451. End of C.S.M.P. Digest
  1452. **********************
  1453.  
  1454.  
  1455.  
  1456.